/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { Buffer } from '../buffer/index.js';
import * as _serializer from './serializer.js';
import * as _encodings from './encodings.js';
import * as _types from './types.js';

function jsonify(content) {
  const contentType = typeof content;
  switch (contentType) {
    case 'string':case 'number':case 'boolean':
      return content;
    case 'object':
      {
        if (Array.isArray(content)) return content.map(item => jsonify(item));
        if (Buffer.isBuffer(content)) return content.toString('base64');
        if (typeof content.toString === 'function' && !(content instanceof _types.Type)) {
          return content.toString();
        }
        throw new Error(`No mechanism to serialize content object: "${content}"`);
      }
    default:
      throw new Error(`Illegal ASN.1 object model content type "${contentType}"`);
  }
}

class JSONSerializer extends _serializer.Serializer {
  serializationImpl(aom) {
    if (Array.isArray(aom)) return aom.map(item => this.serializationImpl(item));

    const {
      tagClass,
      type,
      encoding,
      content
    } = aom;
    const { type: tagClassName } = tagClass;
    const { type: encodingName } = encoding;

    const serialized = {
      tagClass: tagClassName,
      type,
      encoding: encodingName
    };

    if (content != null) {
      serialized.content = encoding.type === _encodings.Constructed.type ? this.serializationImpl(content) : jsonify(content);
    }

    return serialized;
  }
}
// exports.JSONSerializer = JSONSerializer;
export {JSONSerializer}